﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using WorkDAL;
using WorkDAL.Users;
using Common;
using Users;
using WorkDAL.Menu;
using Microsoft.ApplicationBlocks.Updater;
using System.Threading;
using Lapas.Common;
using System.Globalization;

namespace Worker
{
    public partial class MainForm : Form
    {
        private Form currentActivateForm;
        private System.Windows.Forms.ListBox eventList;
        private int manifestDownloaded = 0;
        private Thread pollThread = null;

        public MainForm()
        {
            InitializeComponent();

            CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
            culture.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
            culture.DateTimeFormat.LongDatePattern = "dd MMMM, yyyy";
            Thread.CurrentThread.CurrentCulture = culture;

            this.BackgroundImage = Common.IconsHelper.GetBitmap("Theme");
        }


        private MenuStrip menuStrip;
        private ToolStripMenuItem menuItem;
        private ToolStripMenuItem menuItem2;
        //private ToolStripSeparator menuLine;


        private void MainForm_Load(object sender, EventArgs e)
        {
            //ThreadStart checkUpdateThreadStart = new ThreadStart(CheckAndUpdate);
            //pollThread = new Thread(checkUpdateThreadStart);
            //pollThread.Start();

            //CheckAndUpdate();
            
            Login();
            this.Text = CommonSettings.CompanyName + " - " + CommonSettings.UserName;
        }

        private void Login()
        {
            LoginForm loginForm = new LoginForm();
            loginForm.ShowDialog();
            AddMenu();
            LoadSettings();
        }
        
        private void LoadSettings()
        {
            CommonSettings.ConnectionString = global::Worker.Properties.Settings.Default.WorkerConnectionString;
        }

        private MenuObject Convert2MenuObject(tbMenu item)
        {
            MenuObject menuObject = new MenuObject();
            menuObject.Caption = item.Caption;
            menuObject.Click = item.Click;
            menuObject.Group = item.Group;
            menuObject.Icon = item.Icon;
            menuObject.Id = item.Id;
            menuObject.MenuLevel = item.MenuLevel;
            menuObject.MenuName = item.MenuName;

            return menuObject;
        }

        #region DisplayForm
        private Form GetForm(Type formType)
        {
            foreach (Form clientForm in this.MdiChildren)
            {
                if (clientForm.GetType() == formType)
                {
                    return clientForm;
                }
            }

            return null;
        }

        internal void DisplayForm(Form mdiForm)
        {
            currentActivateForm = GetForm(mdiForm.GetType());

            if (currentActivateForm == null)
            {
                currentActivateForm = mdiForm;
                mdiForm.MdiParent = this;
                mdiForm.Show();
            }
            else
            {
                currentActivateForm.Activate();
            }
            this.Refresh();

        }
        #endregion

        #region Add Menu and Permission
        private void AddMenu()
        {
            
            if (string.IsNullOrEmpty(CommonSettings.UserName))
            {
                return;
            }

            //if (CommonSettings.UserName == "SuperAdmin")
            //{
            //    //Nếu là user SuperAdmin thì chỉ hiện form quản lý users để phân quyền lại
            //    UsersListForm userListForm = new UsersListForm();
            //    DisplayForm(userListForm);
            //}
            //else
            
            string userPermisstionMenu = UserDataAccess.Instance().UserGet(CommonSettings.UserName).Permisstion;

            menuStrip = new MenuStrip();

            this.menuStrip.Location = new System.Drawing.Point(0, 0);
            this.menuStrip.Name = "menuStrip1";
            this.menuStrip.Size = new System.Drawing.Size(292, 24);
            this.menuStrip.TabIndex = 0;
            this.menuStrip.Text = "menuStrip1";

            List<tbMenu> menuLevel1List = MenuDataAccess.Instance().GetMenuLevel1();
            foreach (tbMenu item in menuLevel1List)
            {
                menuItem = new ToolStripMenuItem();

                this.menuItem.Click += new System.EventHandler(MenuItem_Click);

                menuItem.Text = item.Caption;
                menuItem.Name = item.MenuName;
                menuItem.Tag = item.Click;

                if (menuItem.Name != string.Empty)
                    this.menuStrip.Items.AddRange(new ToolStripItem[] { this.menuItem });

                List<tbMenu> menuLevel2List = MenuDataAccess.Instance().GetMenuLevel2(item.Group);

                foreach (tbMenu itemlevel2 in menuLevel2List)
                {
                    menuItem2 = new ToolStripMenuItem();
                    this.menuItem2.Click += new System.EventHandler(this.MenuItem_Click);
                    if (itemlevel2.MenuLevel != 1)
                    {
                        MenuObject menuObject = Convert2MenuObject(itemlevel2);
                        if (menuObject.MenuName != "Line")
                        {

                            menuItem2.Text = itemlevel2.Caption;
                            menuItem2.Name = itemlevel2.MenuName;
                            menuItem2.Tag = itemlevel2.Click;
                            menuItem2.Image = menuObject.IconMenu;


                            if (CommonSettings.UserName == "SuperAdmin")
                            {
                                //Nếu là User SuperAdmin thì chỉ hiện menu Hệ thống
                                if (itemlevel2.Group == "1")
                                    menuItem2.Enabled = true;
                                else
                                    menuItem2.Enabled = false;
                            }
                            else
                            {
                                string permisstionMenu = "," + itemlevel2.Id.ToString().Trim() + ",";
                                if (userPermisstionMenu.Contains(permisstionMenu))
                                    menuItem2.Enabled = true;
                                else
                                    menuItem2.Enabled = false;
                            }

                            // Luôn luôn Enable 2 menu Login và Logout cho người sd
                            if (itemlevel2.MenuName == "Exits" || itemlevel2.MenuName == "Login")
                                menuItem2.Enabled = true;

                            if (menuItem2.Name != string.Empty)
                            this.menuItem.DropDownItems.AddRange(new ToolStripItem[] { this.menuItem2 });
                        }
                        else
                        {
                            this.menuItem.DropDownItems.Add(new ToolStripSeparator());
                        }

                        


                    }
                }

                

                this.Controls.Add(this.menuStrip);
                this.MainMenuStrip = this.menuStrip;
                this.menuStrip.ResumeLayout(false);
                this.menuStrip.PerformLayout();
                //LoadSettings();
            }
        }
        #endregion

        #region Menu Click
        private void MenuItem_Click(object sender, EventArgs e)
        {
            menuItem = (ToolStripMenuItem)sender;

            

            if (menuItem.Name == "Exits")
                this.Close();

            if (menuItem.Name == "Login") //Nếu là đăng nhập lại thì thoát hết các form và remove toàn bộ menu
            {
                foreach (Form clientForm in this.MdiChildren)
                {
                    clientForm.Close();
                }
                this.Controls.Remove(this.menuStrip);
                this.MainMenuStrip = this.menuStrip;
                this.menuStrip.ResumeLayout(false);
                this.menuStrip.PerformLayout();
                Login();
            }

            if (menuItem.Tag != null && menuItem.Name != "Login")
            {
                string formName = menuItem.Tag.ToString();
                    //formName = (new Lapas.Common.Forms.VoucherListForm()).GetType().AssemblyQualifiedName;
                    //DisplayMessage.ShowNotice(formName);

                object oForm = new object();
                Type tForm = Type.GetType(formName);
                if (tForm != null)
                {
                    oForm = Activator.CreateInstance(tForm);
                    DisplayForm((Form)oForm);
                }

            }

        }
        #endregion

        #region Check For Update
        private void updater_DownloadStarted(object sender, DownloadStartedEventArgs e)
        {
            UpdateList("DownloadStarted for manifest: " + e.Manifest.ManifestId);
        }

        private void updater_DownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            UpdateList("DownloadProgress for manifest: " + e.Manifest.ManifestId +
                "- Files: " + e.FilesTransferred + "/" + e.FilesTotal +
                " - Bytes: " + e.BytesTransferred + "/" + e.BytesTotal);
        }

        private void updater_DownloadCompleted(object sender, ManifestEventArgs e)
        {
            UpdateList("DownloadCompleted for manifest: " + e.Manifest.ManifestId);
            manifestDownloaded++;
        }

        private void updater_DownloadError(object sender, ManifestErrorEventArgs e)
        {
            UpdateList("DownloadError for manifest: " + e.Manifest.ManifestId + "\n" + e.Exception.Message);
        }

        private void updater_ActivationInitializing(object sender, ManifestEventArgs e)
        {
            UpdateList("ActivationInitializing for manifest: " + e.Manifest.ManifestId);
        }

        private void updater_ActivationStarted(object sender, ManifestEventArgs e)
        {
            UpdateList("ActivationStarted for manifest: " + e.Manifest.ManifestId);
        }

        private void updater_ActivationInitializationAborted(object sender, ManifestEventArgs e)
        {
            UpdateList("ActivationInitializationAborted for manifest: " + e.Manifest.ManifestId);
            //MessageBox.Show(this, "The Application needs to restart for applying the updates, please restart the application.",
            //    "Auto Inproc Updates", MessageBoxButtons.OK, MessageBoxIcon.Information);

            DisplayMessage.ShowNotice("Chương trình vừa cập nhật phiên bản mới \nHãy khởi động lại để chương trình có thể hoạt động bình thường!");
        }

        private void updater_ActivationError(object sender, ManifestErrorEventArgs e)
        {
            UpdateList("ActivationError for manifest: " + e.Manifest.ManifestId + "\n" + e.Exception.Message);
        }

        private void updater_ActivationCompleted(object sender, ActivationCompleteEventArgs e)
        {
            UpdateList("ActivationCompleted for manifest: " + e.Manifest.ManifestId);
        }

        private delegate void UpdateListDelegate(string displayString);

        private void UpdateList(string displayString)
        {
            if (InvokeRequired)
                BeginInvoke(new UpdateListDelegate(InnerUpdateList), displayString);
            else
                InnerUpdateList(displayString);

        }

        private void InnerUpdateList(string displayString)
        {
            eventList.Items.Add(displayString);
            eventList.Update();
        }

        private void CheckAndUpdate()
        {
            try
            {
                // Get the updater manager
                ApplicationUpdaterManager updater = ApplicationUpdaterManager.GetUpdater();

                // Subscribe for various events
                updater.DownloadStarted += new DownloadStartedEventHandler(updater_DownloadStarted);
                updater.DownloadProgress += new DownloadProgressEventHandler(updater_DownloadProgress);
                updater.DownloadCompleted += new DownloadCompletedEventHandler(updater_DownloadCompleted);
                updater.DownloadError += new DownloadErrorEventHandler(updater_DownloadError);
                updater.ActivationInitializing += new ActivationInitializingEventHandler(updater_ActivationInitializing);
                updater.ActivationStarted += new ActivationStartedEventHandler(updater_ActivationStarted);
                updater.ActivationInitializationAborted += new ActivationInitializationAbortedEventHandler(updater_ActivationInitializationAborted);
                updater.ActivationError += new ActivationErrorEventHandler(updater_ActivationError);
                updater.ActivationCompleted += new ActivationCompletedEventHandler(updater_ActivationCompleted);

                // Loop till the updates are available

                Manifest[] manifests = null;
                while (true)
                {
                    manifests = updater.CheckForUpdates();
                    if (manifests.Length > 0)
                    {
                        // Prompt user if he wants to apply the updates
                        if (DisplayMessage.ShowConfirm("Đã có phiên bản cập nhật mới trên Server \nBạn có muốn cập nhật không?"))
                        {
                            foreach (Manifest m in manifests)
                            {
                                m.Apply = true;
                            }
                            // update the application as per manifest details.
                            updater.Download(manifests, TimeSpan.MaxValue);
                            if (manifestDownloaded == manifests.Length)
                            {
                                updater.Activate(manifests);
                                manifestDownloaded = 0;
                            }

                            foreach (Form clientForm in this.MdiChildren)
                            {
                                clientForm.Close();
                            }
                            this.Close();

                            break;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            catch (ThreadAbortException ex)
            {
                // Do nothing if the thread is being aborted, as we are explicitly doing it
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

    }
}
